/*
 ============================================================================
 Name		: GaborFilter.cpp
 Author	  : lenli
 Version	 : 1.0
 Copyright   : Your copyright notice
 Description : CGaborFilter implementation
 ============================================================================
 */

#include "GaborFilter.h"
#include <e32math.h>
#include <ncvMath.h>

CGaborFilter::CGaborFilter()
	{
	// No implementation required
	}

CGaborFilter::~CGaborFilter()
	{
		iReals->Reset();
		iImags->Reset();
		/*for(TInt i=0;i<iSize;i++)
			delete iReals[i];*/
		delete iReals;
		/*for(TInt i=0;i<iSize;i++)
			delete iImags[i];*/
		delete iImags;
	}

CGaborFilter* CGaborFilter::NewLC(TInt aRadius, TReal32 aAngle, TReal32 aFreq, TReal32 aSigma, TReal32 aPhase)
	{
	CGaborFilter* self = new (ELeave) CGaborFilter();
	CleanupStack::PushL(self);
	self->ConstructL(aRadius, aAngle, aFreq, aSigma, aPhase);
	return self;
	}

CGaborFilter* CGaborFilter::NewL(TInt aRadius, TReal32 aAngle, TReal32 aFreq, TReal32 aSigma, TReal32 aPhase)
	{
	CGaborFilter* self = CGaborFilter::NewLC(aRadius, aAngle, aFreq, aSigma, aPhase);
	CleanupStack::Pop(); // self;
	return self;
	}

void CGaborFilter::ConstructL(TInt aRadius, TReal32 aAngle, TReal32 aFreq, TReal32 aSigma, TReal32 aPhase)
	{		
		// set internal variables
		iSize = 2 * aRadius;
		iXYO = aRadius;	// origin of filter
		iSigma = aSigma;
		iAngle = aAngle;
		iPhase = aPhase;
		iFrequency = aFreq * KPi / 2.0;
				
		// allocate memory for this filter
		//iReals = new TReal32*[iSize];		// real part of filter
		//iImags = new TReal32*[iSize];		// imaginary part of filter
		iReals = new (ELeave) CArrayFixFlat<TReal32>(iSize*iSize) ;
		iImags = new (ELeave) CArrayFixFlat<TReal32>(iSize*iSize) ;

	}

void CGaborFilter::Compute()
	{
		TReal x, y, exponential, sincos;
		TInt matherror;
		
		//precompute sin and cos
		TReal cos, sin, exp;
		matherror = Math::Cos(cos, iAngle);
		matherror = Math::Sin(sin, iAngle);
		matherror = Math::Exp(exp, (-1.0*KPi*KPi)/2.0);
		
		// initialize values of filter
		for ( int i = 0; i < iSize; i++ )
		{
			//iReals[i] = new TReal32[iSize];
			//iImags[i] = new TReal32[iSize];
			
			for ( int j = 0; j < iSize; j++ )
			{
				// offset from origin
				y = (TReal32)( i - iXYO );
				x = (TReal32)( j - iXYO );
				
				// calculate exponential part
				TReal32 t = - ( x*x + y*y ) / iSigma;
				matherror = Math::Exp(exponential, t);
				
				// calculate sin-cos sum
				TReal sintemp, costemp;
				sincos = iFrequency * ( y * cos - x * sin );
				
				//CNokiaCVMath::Ceil1616((sincos*360)/360)
				TReal tmp;
				Math::Round(tmp, sincos/(2*KPi), 0);
				sincos = sincos - tmp * 2 * KPi;
				if(sincos<0)
					sincos = sincos + 2 * KPi;
				
				CNokiaCVMath::SinLUT_Rad(sintemp, sincos);
				CNokiaCVMath::CosLUT_Rad(costemp, sincos);
				
				//matherror = Math::Sin(sintemp, sincos);
				//matherror = Math::Cos(costemp, sincos);
				TReal32 temp1 = exponential * sintemp;
				TReal32 temp2 = exponential * ( costemp - exp);
				
				iReals->AppendL(temp1);
				iImags->AppendL(temp2);
			}
		}
	}

void CGaborFilter::LoadFromFileL(const TDesC& aFileName)
	{
		//before opening file we need a fileserver connection
		RFs fileserver;
		User::LeaveIfError(fileserver.Connect());
		CleanupClosePushL(fileserver);
	 
		RFileReadStream readStream;
		readStream.PushL();// reader on cleanup stack
		User::LeaveIfError(readStream.Open(fileserver, aFileName, EFileRead));
		
		/*CLineReader *liner = CLineReader::NewL(readStream);
		CleanupStack::PushL(liner);		
		
		TInt pos = 0;
		TInt err1= 0;
		while(err1 != KErrEof)
		{
			TBool r = liner->ReadLineL(pos, err1);
			if(r == CLineReader::ELineHasContent)
			{
				TInt length = liner->iBufPtr.Length();
			  	HBufC8* myBuffer = HBufC8::NewLC(length);
			  	*myBuffer = liner->iBufPtr;
			  	
			  	TInt a = (TInt)myBuffer;
			  	RDebug::Print( _L("Line read: %S"), myBuffer);
			  	RDebug::Print(_L("Number read: %d"), a);
			}
		}
		// odstranenie readStream a liner
		CleanupStack::PopAndDestroy(liner);  */
		
		// initialize values of filter
		for ( TInt i = 0; i < iSize; i++ )//riadky
		{					
			for ( TInt j = 0; j < iSize; j++ ) //stlpce
			{
				TReal32 temp = readStream.ReadReal32L();
				iReals->AppendL(temp);
				readStream.ReadL(2);//precitanie medzery
				temp = readStream.ReadReal32L();
				iImags->AppendL(temp);
				readStream.ReadL(2);//prechod na novy riadok
			}
		}
		
	    CleanupStack::PopAndDestroy(&readStream); 
		
		//closing fileserver connection
		fileserver.Close();
		CleanupStack::PopAndDestroy(&fileserver); // destroy fs
	}

void CGaborFilter::SaveToFileL(const TDesC &aFileName)
	{
		//before opening file we need a fileserver connection
		RFs fileserver;
		User::LeaveIfError(fileserver.Connect());
		CleanupClosePushL(fileserver);
		 
		RFileWriteStream writeStream;
		writeStream.PushL();// reader on cleanup stack
		User::LeaveIfError(writeStream.Open(fileserver, aFileName, EFileWrite));
		
		for ( TInt i = 0; i < iSize; i++ )//riadky
		{
		   for ( TInt j = 0; j < iSize; j++ )//stlpce
		   {			   
			   TInt index = i*iSize+j;
			   writeStream.WriteReal32L(iReals->At(index));
			   writeStream.WriteL(_L(" "));
			   writeStream.WriteReal32L(iImags->At(index));
			   writeStream.WriteL(_L("\n"));
			   writeStream.CommitL();
		   }
		}
		
		writeStream.Close();
			
		CleanupStack::PopAndDestroy(&writeStream); 
			
		//closing fileserver connection
		fileserver.Close();
		CleanupStack::PopAndDestroy(&fileserver); // destroy fs
	}
